from typing import TypedDict, List, Optional, Annotated, Dict, Any
from langgraph.graph import add_messages


class CrawlerState(TypedDict):
    """爬虫状态定义"""
    # 输入参数
    html_index: int                     # HTML文件索引（如1.html中的1）
    html_file_path: str                 # 当前处理的HTML文件路径
    url: Optional[str]                  # 当前处理的URL
    
    # 爬取数据
    html_content: Optional[str]         # 当前页面HTML内容
    extracted_info: Dict[str, Any]      # 已提取的信息
    
    # 文件管理
    pending_indices: List[int]          # 待处理的HTML文件索引
    processed_indices: List[int]        # 已处理的文件索引
    
    # 控制参数
    max_files: int                      # 最大处理文件数量
    current_count: int                  # 当前已处理文件数量
    skip_agent_processing: bool         # 是否跳过Agent处理
    
    # 结果输出
    final_result: Optional[Dict[str, Any]]  # 最终结果
    error_message: Optional[str]        # 错误信息
    
    # 消息历史
    messages: Annotated[list, add_messages]  # AI对话历史


class ExtractedInfo(TypedDict):
    """提取的信息结构"""
    emails: List[str]                   # 邮箱列表
    phones: List[str]                   # 电话列表
    social_media: Dict[str, str]        # 社交媒体信息
    page_links: List[str]               # 页面关键链接列表
    company_info: Dict[str, Any]        # 公司信息
    remarks: str                        # 备注信息


class CompanyInfo(TypedDict):
    """公司信息结构"""
    business: Optional[str]             # 业务范围
    scale: Optional[str]                # 公司规模
    industry: Optional[str]             # 行业类型
    location: Optional[str]             # 公司位置
    description: Optional[str]          # 公司描述


class SocialMedia(TypedDict):
    """社交媒体信息结构"""
    twitter: Optional[str]              # Twitter账号
    facebook: Optional[str]             # Facebook账号
    linkedin: Optional[str]             # LinkedIn账号
    instagram: Optional[str]            # Instagram账号
    whatsapp: Optional[str]             # WhatsApp号码
    youtube: Optional[str]              # YouTube频道
    tiktok: Optional[str]               # TikTok账号


def create_initial_state(html_index: int, url: Optional[str] = None, max_files: int = 5) -> CrawlerState:
    """创建初始状态"""
    return CrawlerState(
        html_index=html_index,
        html_file_path="",
        url=url,
        html_content=None,
        extracted_info={
            "emails": [],
            "phones": [],
            "social_media": {},
            "page_links": [],
            "company_info": {},
            "remarks": ""
        },
        pending_indices=[],
        processed_indices=[],
        max_files=max_files,
        current_count=0,
        skip_agent_processing=False,
        final_result=None,
        error_message=None,
        messages=[]
    )


def is_info_complete(extracted_info: Dict[str, Any]) -> bool:
    """
    Agent评估：当前页面信息是否足够完整
    
    按照文档中的信息完整性评估标准：
    - 必要信息：至少获取到邮箱或电话号码中的一项
    - 补充信息：社交媒体链接、公司规模、业务范围等
    - 信息质量：联系信息的有效性和准确性
    - 页面类型：判断是否为公司官网主页、联系页面等关键页面
    """
    # 必要信息检查：至少获取到邮箱或电话号码中的一项
    emails = extracted_info.get("emails", [])
    phones = extracted_info.get("phones", [])
    has_essential_contact = bool(emails or phones)
    
    if not has_essential_contact:
        return False
    
    # 补充信息检查
    social_media = extracted_info.get("social_media", {})
    company_info = extracted_info.get("company_info", {})
    
    # 社交媒体信息评分
    social_score = len([v for v in social_media.values() if v]) if social_media else 0
    
    # 公司信息评分
    company_score = 0
    if company_info:
        # 检查业务范围
        if company_info.get("business") or company_info.get("description"):
            company_score += 2
        # 检查公司规模
        if company_info.get("scale"):
            company_score += 1
        # 检查行业类型
        if company_info.get("industry"):
            company_score += 1
        # 检查位置信息
        if company_info.get("location"):
            company_score += 1
    
    # 信息质量评估
    quality_score = 0
    # 邮箱质量（包含@符号且格式合理）
    valid_emails = [email for email in emails if '@' in email and '.' in email.split('@')[-1]]
    quality_score += len(valid_emails)
    
    # 电话质量（包含数字且长度合理）
    valid_phones = [phone for phone in phones if any(c.isdigit() for c in phone) and len(phone.replace(' ', '').replace('-', '').replace('+', '')) >= 7]
    quality_score += len(valid_phones)
    
    # 综合评分：必要信息 + 补充信息 + 质量评分
    total_score = quality_score + social_score + company_score
    
    # 完整性判断标准：
    # 1. 必须有有效的联系方式（邮箱或电话）
    # 2. 总分达到4分以上认为信息比较完整
    # 3. 或者同时有邮箱、电话和公司信息
    is_complete = (
        has_essential_contact and (
            total_score >= 4 or
            (valid_emails and valid_phones and company_score > 0)
        )
    )
    
    return is_complete


def merge_extracted_info(current_info: Dict[str, Any], new_info: Dict[str, Any]) -> Dict[str, Any]:
    """合并提取的信息"""
    merged = current_info.copy()
    
    # 合并邮箱列表
    if new_info.get("emails"):
        merged["emails"] = list(set(merged.get("emails", []) + new_info["emails"]))
    
    # 合并电话列表
    if new_info.get("phones"):
        merged["phones"] = list(set(merged.get("phones", []) + new_info["phones"]))
    
    # 合并社交媒体信息
    if new_info.get("social_media"):
        merged["social_media"] = {**merged.get("social_media", {}), **new_info["social_media"]}
    
    # 合并页面链接列表
    if new_info.get("page_links"):
        merged["page_links"] = list(set(merged.get("page_links", []) + new_info["page_links"]))
    
    # 合并公司信息
    if new_info.get("company_info"):
        merged["company_info"] = {**merged.get("company_info", {}), **new_info["company_info"]}
    
    # 更新备注
    if new_info.get("remarks"):
        current_remarks = merged.get("remarks", "")
        if current_remarks:
            merged["remarks"] = f"{current_remarks}; {new_info['remarks']}"
        else:
            merged["remarks"] = new_info["remarks"]
    
    return merged